///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef __BUOLA_TTY_CCONTROLLEDIO_H__
#define __BUOLA_TTY_CCONTROLLEDIO_H__

#include <buola/buola.h>
#include <buola/tty/ccompletion.h>
#include <buola/utility/ccursorpos.h>
#include <buola/utility/usignal.h>

namespace buola { namespace tty {

///\addtogroup tty
///@{

class CControlledIO : public UUncopiable
{
public:
    struct SBlock
    {
        SBlock(const std::wstring &pString,int pIS,int pIE,int pOS,int pOE,bool pNL,bool pNP)
            :   mString(&pString)
            ,   mIS(pIS)
            ,   mIE(pIE)
            ,   mOS(pOS)
            ,   mOE(pOE)
            ,   mNL(pNL)
            ,   mNP(pNP)
        {}
            
        const std::wstring *mString;
        int mIS,mIE; //start and end in string (lIE exclusive)
        int mOS,mOE; //start and end in screen (lOE exclusive)
        bool mNL;    //print a newline after this block
        bool mNP;    //it is a non-printing block
    };
    
    CControlledIO(CScreen *pScreen=nullptr);
    ~CControlledIO();
    
    void Start();
    void End();

    CCursorPos BreakString(const std::wstring &pString,std::vector<SBlock> &pBlocks,int pIS,const CCursorPos &pOS);
    void OutputBlocks(std::vector<SBlock>::const_iterator pS,std::vector<SBlock>::const_iterator pE,
                      int pFrom=0,const std::pair<int,int> &pSelection=std::make_pair(0,0));
    
    const CCursorPos &GetCursor()   {   return mCursor;         }
    int GetWidth()                  {   return mWidth;          }
    int GetHeight()                 {   return mHeight;         }
    bool WinSizeChanged()           {   return mWINCHSignalled; }

    void MoveCursor(const CCursorPos &pPos);
    void SetCursor(bool pOn);

    void ClearToEnd();
    void ClearToEndOf(int pR);
    void ClearToEOL();
    void NewLine();
    void Output(const std::wstring &pStr,int pLen=-1);
    void Output(const std::string &pStr,int pLen=-1)    {   Output(utf32(pStr),pLen);   }

    wchar_t GetWChar();
    char GetChar();    

private:
    void OnWINCH();

public:
    USignal<void()> sWinSizeChanged;

private:
    CScreen *mScreen;
    
    int mWidth;
    int mHeight;

    CCursorPos mCursor;
    CCursorPos mBottom;
    
    bool mOn;
    bool mWaitingInput;
    bool mWINCHSignalled;
};

///@}

/*namespace tty*/ } /*namespace buola*/ }

#endif
